package com.jt.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @outhor fufeixiang
 * @date 2021-04-26
 */
@Component
//表示该类为AOP切面
//Spring容器默认不能识别切面注解,需要手动配置
@Aspect
public class SpringAOP {
/*
* 切入点表达式练习
* 1.within(com.jt.*.DeptServiceImpl)  代表一级包下的类
* 2.within(com.jt..*.DeptServiceImpl) 代表多级包下的类
* 3.within(com.jt..*)  包下的所有类
* */

//    @Before("bean(deptServiceImpl)")
//    @Before("within(com.jt.service.DeptServiceImpl)")
//    @Before("execution(* com.jt..*.*(..))")

//定义切入点表达式
    @Pointcut("@annotation(com.jt.anno.Cache)")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        System.out.println("获取目标对象的类型"+joinPoint.getTarget().getClass());
        System.out.println("获取目标对象的类名"+joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("获取目标对象的方法名"+joinPoint.getSignature().getName());
        System.out.println("获取目标对象的方法参数"+ Arrays.toString(joinPoint.getArgs()));

        System.out.println("我是before通知");
    }
    @AfterReturning(pointcut = "pointCut()",returning = "result")
    public void afterReturning(Object result){

        System.out.println("方法的返回值为:"+result);
        System.out.println("我是afterReturning通知");

    }
    @AfterThrowing(pointcut = "pointCut()",throwing ="e")
    public void afterTrowing(Exception e){

        System.out.println("获取异常信息："+e.getMessage());
        System.out.println("获取异常类型："+e.getClass());
        System.out.println("我是afterThrowing通知");
    }
    @After("pointCut()")
    public void after(){
        System.out.println("我是after通知");
    }
    /*
    * 关于环绕通知的
    * 作用：可以控制目标方法是否执行
    *
    * */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object result = null;
        try {
            System.out.println("环绕通知开始");
            //执行目标方法
            long start = System.currentTimeMillis();
            result = joinPoint.proceed();
            long end = System.currentTimeMillis();
            System.out.println("耗时"+(end-start));
            return result;
        }catch (Throwable throwable){
            throwable.printStackTrace();
        }
        System.out.println("环绕通知结束");
        return result;
    }



}
